/**
 * 数组语法
 */

// 创建数组的第一种方式, 创建一个空数组
var array = new Array();
console.log('array:' + typeof array)    // array:object


// 2.使用数组字面量创建空的数组
var arr = [];
// 3.使用数组字面量方式创建带初始值的数组
// 数组中可以放任意数据类型!!! 不同于Java中数组, 但Java集合中可以放任何数据类型
var newVar = [1, 2, 3, 4, 5, '5'];
newVar.forEach(item => {
  console.log(`${item} | typeof item ${typeof item}`)
})
// 1 | typeof item number
// 2 | typeof item number
// 3 | typeof item number
// 4 | typeof item number
// 5 | typeof item number
// 5 | typeof item string


/**
 * Array.isArray() 用于判断一个对象是否为数组
 */
var obj = {};
console.log(`Array.isArray(arr): ${Array.isArray(arr)}`); // true
console.log(`Array.isArray(obj): ${Array.isArray(obj)}`); // false

/**
 * 添加删除数组元素的方法
 * 下面四种方法都修改了原数组!!!
 * push(参数1...)  ->  添加   在数组尾部添加一个或多个元素     return: 并返回新的长度
 * pop()          ->  删除   删除数组最后一个元素            return: 返回它删除的元素的值
 * #
 * unshift(参数1...)  -> 添加   在数组头部添加一个或多个元素     return: 并返回新的长度
 * shift()           -> 删除    删除数组第一个元素             return: 返回第一个元素的值
 */
var newLength = arr.push(-1, 0);
console.log(`newLength: ${newLength}`);
console.log(arr);                       // [ 1, 12, -1, 0 ]

var unshiftNewLength = arr.unshift(-10, -5, -4);
console.log(`unshiftNewLength: ${unshiftNewLength}`);
console.log(arr);


/**
 * 数组索引方法
 * indexOf()函数签名        数组中查找给定元素的第一个索引, 不存在返回-1
 * indexOf(searchElement: T, fromIndex?: number): number;
 *#
 * lastIndexOf()函数签名    数组中查找给定元素的最后一个索引, 不存在返回-1
 * lastIndexOf(searchElement: T, fromIndex?: number): number;
 */

var strArr = ['1', '2', '3', '4', '5', '6', '3'];
console.log(`strArr.indexOf('3'): ${strArr.indexOf('3')}`);     // strArr.indexOf('3'): 2
console.log(`strArr.lastIndexOf(): ${strArr.lastIndexOf('3')}`);// strArr.lastIndexOf(): 6


/**
 * 数组转出字符串
 * toString()           把数组转换成字符串, 用逗号分隔每一项
 * #
 * join(separator?: string): string;
 * join('分隔符')        把数组转换成字符串, 自定义分隔符, join不传入参数, 则分隔符为 , 逗号
 */

console.log(`strArr.toString(): ${strArr.toString()}`); // strArr.toString(): 1,2,3,4,5,6,3
console.log(`strArr.join(''): ${strArr.join('')}`);     // strArr.join(''): 1234563
console.log(`strArr.join('-'): ${strArr.join('-')}`);   // strArr.join('-'): 1-2-3-4-5-6-3

/**
 * 单词   slice -> 切, 裁       splice -> 拼接
 * #
 * concat() 连接两个或多个数组                   返回一个新的数组
 * slice()  数组截取slice(begin, end)           返回被截取项目的新数组
 * splice() 数组删除splice(begin, delCount)     返回被删除的新数组, 注意. 这个会影响到原数组
 */

var arr01 = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
var arr02 = ['h', 'i', 'j', 'k', 'm', 'l', 'n'];
console.log(`Before ------- arr02: ${arr02.toString()}`)// // Before ------- arr02: h,i,j,k,m,l,n

var newArr = arr02.splice(0, 4);
console.log(`After ------- arr02: ${arr02.toString()}`) // After ------- arr02: m,l,n
console.log(`newArr: ${newArr.toString()}`);             // newArr: h,i,j,k


const numArr = [1, 2, 3, 4, 5];

// reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
// reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
let accRes = numArr.reduce((acc, cur, index) => {
  console.log(`第 ${index} reduce轮, acc累加器: ${acc} cur当前值: ${cur} `)
  return acc + cur;
})

console.log(`accRes: ${accRes}`)

// reduce 将二维数组转化为一位数组
const douArr = [[1, 2], [3, 4], [5, 6, 7]];

/**
 * 这里是否需要给 acc, 一个默认的初始值 []
 * @type {number[]}
 */
let newVar1 = douArr.reduce((acc, cur) => {
  // {} 不省略的话, 如果有函数有返回值的话, 一定要写return
  return acc.concat(cur)
})
console.log(newVar1)


// 计算数组中每个元素出现的次数
// 这里给 acc 一个默认的初始值 new Map(), 所以返回结果泛型类型也是 Map 类型的
// reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let mapRes = names.reduce((acc, cur, index, arr) => {
  if (!acc.has(cur)) {
    acc.set(cur, 1)
  } else {
    acc.set(cur, acc.get(cur) + 1)
  }
  return acc;
}, new Map());

// Map(4) { 'Alice' => 2, 'Bob' => 1, 'Tiff' => 1, 'Bruce' => 1 }
console.log(mapRes)
